﻿#include "AccountInfo.h"
#include "../../Shared/Globals.h"

using namespace Server::MirNetwork;
using namespace Server::MirEnvir;
namespace C = ClientPackets;

namespace Server::MirDatabase
{

    Server::MirEnvir::Envir *AccountInfo::getEnvir()
    {
        return Envir::getMain();
    }

    AccountInfo::AccountInfo()
    {

    }

    AccountInfo::AccountInfo(C::NewAccount *p)
    {
        AccountID = p->AccountID;
        Password = p->Password;
        UserName = p->UserName;
        SecretQuestion = p->SecretQuestion;
        SecretAnswer = p->SecretAnswer;
        EMailAddress = p->EMailAddress;

        BirthDate = p->BirthDate;
        CreationDate = getEnvir()->getNow();
    }

    AccountInfo::AccountInfo(BinaryReader *reader)
    {
        Index = reader->ReadInt32();

        AccountID = reader->ReadString();
        Password = reader->ReadString();

        UserName = reader->ReadString();
        BirthDate = DateTime::FromBinary(reader->ReadInt64());
        SecretQuestion = reader->ReadString();
        SecretAnswer = reader->ReadString();
        EMailAddress = reader->ReadString();

        CreationIP = reader->ReadString();
        CreationDate = DateTime::FromBinary(reader->ReadInt64());

        Banned = reader->ReadBoolean();
        BanReason = reader->ReadString();
        ExpiryDate = DateTime::FromBinary(reader->ReadInt64());

        LastIP = reader->ReadString();
        LastDate = DateTime::FromBinary(reader->ReadInt64());

        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            CharacterInfo *tempVar = new CharacterInfo(reader);
            tempVar->AccountInfo = this;
            Characters.push_back(tempVar);

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar' statement was not added since tempVar was passed to a method or constructor. Handle memory management manually.
        }

        if (Envir::LoadVersion > 75)
        {
            HasExpandedStorage = reader->ReadBoolean();
            ExpandedStorageExpiryDate = DateTime::FromBinary(reader->ReadInt64());
        }

        Gold = reader->ReadUInt32();
        if (Envir::LoadVersion >= 63)
        {
            Credit = reader->ReadUInt32();
        }

        count = reader->ReadInt32();

        Array::Resize(Storage, count);

        for (int i = 0; i < count; i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            UserItem *item = new UserItem(reader, Envir::LoadVersion, Envir::LoadCustomVersion);
            if (getEnvir()->BindItem(item) && i < Storage.size())
            {
                Storage[i] = item;
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete item' statement was not added since item was passed to a method or constructor. Handle memory management manually.
        }

        if (Envir::LoadVersion >= 10)
        {
            AdminAccount = reader->ReadBoolean();
        }
        if (!AdminAccount)
        {
            for (int i = 0; i < Characters.size(); i++)
            {
                if (Characters[i] == nullptr)
                {
                    continue;
                }
                if (Characters[i]->Deleted)
                {
                    continue;
                }
                if ((DateTime::Now - Characters[i]->LastLogoutDate).TotalDays > 13)
                {
                    continue;
                }
                if ((Characters[i]->Level >= getEnvir()->RankBottomLevel[0]) || (Characters[i]->Level >= getEnvir()->RankBottomLevel[static_cast<unsigned char>(Characters[i]->Class) + 1]))
                {
                    getEnvir()->CheckRankUpdate(Characters[i]);
                }
            }
        }
    }

    void AccountInfo::Save(BinaryWriter *writer)
    {
        writer->Write(Index);
        writer->Write(AccountID);
        writer->Write(Password);

        writer->Write(UserName);
        writer->Write(BirthDate.ToBinary());
        writer->Write(SecretQuestion);
        writer->Write(SecretAnswer);
        writer->Write(EMailAddress);

        writer->Write(CreationIP);
        writer->Write(CreationDate.ToBinary());

        writer->Write(Banned);
        writer->Write(BanReason);
        writer->Write(ExpiryDate.ToBinary());

        writer->Write(LastIP);
        writer->Write(LastDate.ToBinary());

        writer->Write(Characters.size());
        for (int i = 0; i < Characters.size(); i++)
        {
            Characters[i]->Save(writer);
        }

        writer->Write(HasExpandedStorage);
        writer->Write(ExpandedStorageExpiryDate.ToBinary());
        writer->Write(Gold);
        writer->Write(Credit);
        writer->Write(Storage.size());
        for (int i = 0; i < Storage.size(); i++)
        {
            writer->Write(Storage[i] != nullptr);
            if (Storage[i] == nullptr)
            {
                continue;
            }

            Storage[i]->Save(writer);
        }
        writer->Write(AdminAccount);
    }

    std::vector<SelectInfo*> AccountInfo::GetSelectInfo()
    {
        std::vector<SelectInfo*> list;

        for (int i = 0; i < Characters.size(); i++)
        {
            if (Characters[i]->Deleted)
            {
                continue;
            }
            list.push_back(Characters[i]->ToSelectInfo());
            if (list.size() >= Globals::MaxCharacterCount)
            {
                break;
            }
        }

        return list;
    }

    int AccountInfo::ExpandStorage()
    {
        if (Storage.size() == 80)
        {
            Array::Resize(Storage, Storage.size() + 80);
        }

        return Storage.size();
    }
}
